package com.xfyuao.util;

import java.util.ArrayList;
import java.util.List;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

// mybatis plus 根据表生成entity、mapper、mapper.xml、service、service.impl、controller
public class CodeGenerator {

	private static String url = "jdbc:mysql://localhost:3306/mp?serverTimezone=GMT%2B8";
	private static String username = "root";
	private static String password = "admin";
	private static String dirverName = "com.mysql.jdbc.Driver";
	private static String author = "xfyuao";// 作者
	private static String parent = "com.xfyuao";// 包前缀
	private static String[] tableArray = { "stu" };// 需要生成代码的表
	// 需要生成的包的名字，不需要生成以空字符或null代替
	private static String entity = "templates/entity.java";
	private static String mapper = "templates/mapper.java";
	private static String service = "templates/service.java";
	private static String serviceImpl = "templates/serviceImpl.java";
	//controller层包名已经在90行修改为web，但模板不变
	private static String controller = "templates/controller.java";

	public static void main(String[] args) {

		AutoGenerator mpg = new AutoGenerator();
		// 选择 freemarker 引擎，默认 Velocity
		mpg.setTemplateEngine(new FreemarkerTemplateEngine());

		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setAuthor(author);
		gc.setFileOverride(true);// 覆盖同名文件
		gc.setOpen(false);// 不要打开生成后的目录
		String projectPath = System.getProperty("user.dir");// 获取项目根目录
		gc.setOutputDir(projectPath + "/src/main/java");// 设置代码生成的目录
		gc.setBaseResultMap(true);// mapper.xml中生成resultMap，默认false
		/* 自定义文件命名，注意 %s 会自动填充表实体属性！ */
		gc.setServiceName("%sService");// 默认生成的service接口会以I开头
		// gc.setActiveRecord(false);//ActiveRecord模式，默认false，实体类会继承Model<T>，可以使用实体类crud
		// gc.setSwagger2(true);//开启 swagger2 模式 默认false
		// gc.setIdType(IdType.AUTO);//主键生成策略 默认自动
		// gc.setEnableCache(false);// mapper.xml 二级缓存，默认false
		mpg.setGlobalConfig(gc);

		// 数据源配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(DbType.MYSQL);//设置数据库类型
		/*dsc.setTypeConvert(new MySqlTypeConvert() {
		    @Override
		    public DbColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
		        System.out.println("转换类型：" + fieldType);
		        //tinyint转换成Boolean
		        if (fieldType.toLowerCase().contains("tinyint")) {
		            return DbColumnType.BOOLEAN;
		        }
		        //将数据库中datetime转换成date
		        if (fieldType.toLowerCase().contains("datetime")) {
		            return DbColumnType.DATE;
		        }
		        return (DbColumnType) super.processTypeConvert(globalConfig, fieldType);
		    }
		
		});*/
		dsc.setUrl(url);
		dsc.setUsername(username);
		dsc.setPassword(password);
		dsc.setDriverName(dirverName);
		
		mpg.setDataSource(dsc);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		// strategy.setCapitalMode(true);// 全局大写命名 ORACLE 注意
		// strategy.setTablePrefix(new String[]{""});// 表前缀
		strategy.setNaming(NamingStrategy.underline_to_camel);// 表名生成策略，下划线转驼峰
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);// 列名下划线转驼峰
		strategy.setInclude(tableArray); // 需要生成的表
		// strategy.setExclude(new String[]{"test"}); // 排除生成的表
		strategy.setEntityLombokModel(true);// 实体类使用lombok
		strategy.setRestControllerStyle(true); // 生成 @RestController 控制器
		strategy.setLogicDeleteFieldName("is_delete"); // 逻辑删除属性名称

		// strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");// 自定义实体父类
		// strategy.setSuperEntityColumns(new String[] { "test_id", "age"});//自定义实体，公共字段
		// strategy.setSuperMapperClass("com.baomidou.mybatisplus.core.mapper.BaseMapper");//自定义mapper父类
		// strategy.setSuperServiceClass("com.baomidou.mybatisplus.extension.service.IService");//自定义service父类
		// strategy.setSuperServiceImplClass("com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");//自定义service实现类父类
		// strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");//自定义Controller父类
		// 【实体】是否生成字段常量（默认 false）
		// public static final String ID = "test_id";
		// strategy.setEntityColumnConstant(true);
		// 【实体】是否为构建者模型（默认 false）
		// public User setName(String name) {this.name = name; return this;}
		// strategy.setEntityBuilderModel(true);
		mpg.setStrategy(strategy);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setParent(parent);
		pc.setController("web");// controller改成web
		mpg.setPackageInfo(pc);

		// 注入自定义配置，可以在 VM 中使用 cfg.abc 【可无】
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
			}
		};
		// 如果模板引擎是 freemarker
		String templatePath = "/templates/mapper.xml.ftl";
		List<FileOutConfig> focList = new ArrayList<>();
		// 调整 xml 生成目录，默认在mapper.xml包下
		focList.add(new FileOutConfig(templatePath) {
			@Override
			public String outputFile(TableInfo tableInfo) {
				// 自定义输出文件名 ， 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化！！
				return projectPath + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper"
						+ StringPool.DOT_XML;
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);
		TemplateConfig tc = new TemplateConfig();
		// 关闭默认 xml 生成，已经在src/main/resources/mapper下生成
		tc.setXml(null);
		tc.setEntity(entity);
		tc.setMapper(mapper);
		tc.setService(service);
		tc.setServiceImpl(serviceImpl);
		tc.setController(controller);
		mpg.setTemplate(tc);

		// 执行生成
		mpg.execute();

	}
}